home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / utils / agrepsrc.zoo / sgrep.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  19KB  |  686 lines

  1. /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
  2. #include <stdio.h>
  3. #define MAXSYM  256
  4. #define MAXMEMBER 8192
  5. #define    CHARTYPE    unsigned char
  6. #define MaxError 20
  7. #define MAXPATT 256
  8. #define MAXLINE 1024
  9. #define MaxCan  2048
  10. #define BLOCKSIZE    8192
  11. #define MAX_SHIFT_2  4096
  12. #define ON      1
  13. #define LOG_ASCII 8
  14. #define LOG_DNA  3
  15. #define MAXMEMBER_1 65536
  16. #define LONG_EXAC  20
  17. #define LONG_APPX  24
  18. #define W_DELIM    2
  19.  
  20. extern COUNT, FNAME, SILENT, FILENAMEONLY, num_of_matched;
  21. extern DNA ;  /* DNA flag is set in checksg when pattern is DNA pattern and
  22.          p_size > 16  */
  23. extern WORDBOUND, WHOLELINE, NOUPPER;
  24. extern unsigned char CurrentFileName[],  Progname[]; 
  25. extern unsigned Mask[];
  26. extern unsigned endposition;
  27.  
  28. unsigned char BSize;                /* log_c m   */
  29. unsigned char char_map[MAXSYM];
  30.     
  31.  
  32. /* data area */
  33. int shift_1;
  34. CHARTYPE SHIFT[MAXSYM];
  35. CHARTYPE MEMBER[MAXMEMBER];
  36. CHARTYPE pat[MAXPATT];
  37. unsigned Hashmask;
  38. char MEMBER_1[MAXMEMBER_1];
  39. CHARTYPE TR[MAXSYM];
  40.  
  41. char_tr(pat, m)
  42.     unsigned char *pat;
  43.     int *m;
  44. {
  45. int i;
  46. unsigned char temp[MAXPATT];
  47.     for(i=0; i<MAXSYM; i++) TR[i] = i;
  48.     if(NOUPPER) {
  49.         for(i='A'; i<= 'Z'; i++) TR[i] = i + 'a' - 'A';
  50.     }
  51.     if(WORDBOUND) { /* SUN: To be added to be more complete */
  52.         TR['\n'] = TR['\t'] = TR[' '] = TR[','] = TR[';'] = TR[':'] = 
  53.             TR['!'] = TR['"'] = TR['?'] = TR['<'] = TR['>'] = 
  54.         TR['='] = TR['['] = TR[']'] = TR['\''] =
  55.             TR['('] = TR[')'] = TR['$'] = TR['/'] = TR['\\'] = W_DELIM;
  56.     }
  57.     if(WHOLELINE) {
  58.         memcpy(temp, pat, *m);
  59.         pat[0] = '\n';
  60.         memcpy(pat+1, temp, *m);
  61.         pat[*m+1] = '\n';
  62.         pat[*m+2] = 0;
  63.         *m = *m + 2;
  64.     }
  65. }
  66.  
  67. sgrep(pat, m, fd, D)
  68. CHARTYPE *pat;  int fd, m, D;
  69.     CHARTYPE text[BLOCKSIZE+2*MAXLINE+MAXPATT]; /* input text stream */
  70.     int offset = 2*MAXLINE;
  71.     int buf_end, num_read, i, start, end, residue = 0;
  72.     if(pat[0] == '^' || pat[0] == '$') pat[0] = '\n';
  73.     if(pat[m-1] == '^' || pat[m-1] == '$') pat[m-1] = '\n';
  74.     char_tr(pat, &m);   /* will change pat, and m if WHOLELINE is ON */
  75.     text[offset-1] = '\n';  /* initial case */
  76.     for(i=0; i < MAXLINE; i++) text[i] = 0;   /* security zone */
  77.     start = offset;   
  78.     if(WHOLELINE) start--;
  79.     if(m >= MAXPATT) {
  80.          fprintf(stderr, "%s: pattern too long\n", Progname);
  81.          exit(2);
  82.     }
  83.     if(D == 0) {
  84.     if(m > LONG_EXAC) m_preprocess(pat);
  85.     else prep_bm(pat, m);
  86.     }
  87.     else if (DNA) prep4(pat, m);
  88.      else     if(m >= LONG_APPX) am_preprocess(pat);
  89.         else {
  90.             prep(pat, m, D);
  91.             initmask(pat, Mask, m, 0, &endposition); 
  92.         }
  93.     for(i=1; i<=m; i++) text[BLOCKSIZE+offset+i] = pat[m-1];
  94.         /* to make sure the skip loop in bm() won't go out of bound */
  95.     while( (num_read = read(fd, text+offset, BLOCKSIZE)) > 0) 
  96.     {
  97.        buf_end = end = offset + num_read -1 ;
  98.        if(num_read < BLOCKSIZE) if(text[end] != '\n') text[++end] = '\n';
  99.        while(text[end]  != '\n' && end > offset) end--;
  100.        residue = buf_end - end + 1 ;
  101.        text[start-1] = '\n';
  102.        if(D==0)  {
  103.         if(m > LONG_EXAC) monkey(pat, m, text+start, text+end);
  104.         else bm(pat, m, text+start, text+end);
  105.        }
  106.        else {
  107.         if(DNA) monkey4( pat, m, text+start, text+end, D  );
  108.         else {
  109.           if(m >= LONG_APPX) a_monkey(pat, m, text+start, text+end, D);
  110.           else       agrep(pat, m, text+start, text+end, D);
  111.         }
  112.        }
  113.        if(FILENAMEONLY && num_of_matched) {
  114.             printf("%s\n", CurrentFileName);
  115.             return; }
  116.        start = offset - residue ;
  117.        if(start < MAXLINE) {
  118.             start = MAXLINE; 
  119.        }
  120.        strncpy(text+start, text+end, residue);
  121.        start++;
  122.     } /* end of while(num_read = ... */
  123.     return;
  124. } /* end sgrep */
  125.  
  126. /* SUN: bm assumes that the content of text[n]...text[n+m-1] is 
  127. pat[m-1] such that the skip loop is guaranteed to terminated */
  128.  
  129. bm(pat, m, text, textend)
  130.     CHARTYPE *text, *textend, *pat;  int m;
  131. {
  132. register int shift;
  133. register int  m1, j, d1; 
  134.  
  135. /*
  136. printf("%d\t", textend - text);
  137. printf("%c, %c", *text, *textend);
  138. */
  139.  
  140. d1 = shift_1;    /* at least 1 */
  141. m1 = m - 1;
  142. shift = 0;       
  143. while (text <= textend) {
  144.     shift = SHIFT[*(text += shift)];
  145.     while(shift) {          
  146.         shift = SHIFT[*(text += shift)];
  147.         shift = SHIFT[*(text += shift)];
  148.         shift = SHIFT[*(text += shift)];
  149.     }
  150.         j = 0;
  151.         while(TR[pat[m1 - j]] == TR[*(text - j)]) {
  152.             if(++j == m)  break;       /* if statement can be
  153.                             saved, but for safty ... */
  154.         }
  155.             if (j == m ) { 
  156.             if(text > textend) return;
  157.             if(WORDBOUND) {
  158.                 if(TR[*(text+1)] != W_DELIM) goto CONT;
  159.                 if(TR[*(text-m)] != W_DELIM) goto CONT;
  160.             }
  161.             num_of_matched++;
  162.             if(FILENAMEONLY) return;
  163.             if(!(COUNT)) {
  164.                 if(FNAME) printf("%s: ", CurrentFileName);
  165.                 while(*(--text) != '\n');
  166.                 while(*(++text) != '\n') putchar(*(text));
  167.                 putchar(*text);
  168.             }
  169.             else { while(*text != '\n') text++; } 
  170. CONT:
  171.             shift = 1;
  172.                 }
  173.         else shift = d1;
  174.   }
  175. return;
  176. }
  177.  
  178.   
  179. /* initmask() initializes the mask table for the pattern                    */ 
  180. /* endposition is a mask for the endposition of the pattern                 */
  181. /* endposition will contain k mask bits if the pattern contains k fragments */
  182. initmask(pattern, Mask, m, D, endposition)
  183. CHARTYPE *pattern; unsigned *Mask; register int m, D; unsigned *endposition;
  184. {
  185.   register unsigned Bit1, c;
  186.   register int i, j, frag_num;
  187.  
  188.   Bit1 = 1 << 31;    /* the first bit of Bit1 is 1, others 0.  */
  189.   frag_num = D+1; *endposition = 0;
  190.   for (i = 0; i < frag_num; i++) *endposition = *endposition | (Bit1 >> i);
  191.   *endposition = *endposition >> (m - frag_num);
  192.   for(i = 0; i < m; i++) 
  193.           if (pattern[i] == '^' || pattern[i] == '$') {
  194.               pattern[i] = '\n'; 
  195.           }
  196.   for(i = 0; i < MAXSYM; i++) Mask[i] = ~0;
  197.   for(i = 0; i < m; i++)     /* initialize the mask table */
  198.   {  c = pattern[i];
  199.      for ( j = 0; j < m; j++)
  200.            if( c == pattern[j] )
  201.                Mask[c] = Mask[c] & ~( Bit1 >> j ) ;
  202.   }
  203. }
  204.  
  205. prep(Pattern, M, D)             /* preprocessing for partitioning_bm */
  206.     CHARTYPE *Pattern;  /* can be fine-tuned to choose a better partition */
  207.     register int M, D;
  208. {
  209. register int i, j, k, p, shift;
  210. register unsigned m;
  211. unsigned hash, b_size = 3;
  212.     m = M/(D+1);
  213.     p = M - m*(D+1);
  214.     for (i = 0; i < MAXSYM; i++) SHIFT[i] = m;
  215.     for (i = M-1; i>=p ; i--) {
  216.         shift = (M-1-i)%m;
  217.         hash = Pattern[i];
  218.         if(SHIFT[hash] > shift) SHIFT[hash] = shift;
  219.     }
  220. #ifdef DEBUG
  221.     for(i=0; i<M; i++) printf(" %d,", SHIFT[Pattern[i]]);
  222.     printf("\n");
  223. #endif
  224.     shift_1 = m;
  225.     for(i=0; i<D+1; i++) {
  226.         j = M-1 - m*i;
  227.         for(k=1; k<m; k++) {
  228.             for(p=0; p<D+1; p++) 
  229.                 if(Pattern[j-k] == Pattern[M-1-m*p]) 
  230.                     if(k < shift_1) shift_1 = k;
  231.         }
  232.     }
  233. #ifdef DEBUG
  234.     printf("\nshift_1 = %d", shift_1);
  235. #endif
  236.     if(shift_1 == 0) shift_1 = 1;
  237.     for(i=0; i<MAXMEMBER; i++) MEMBER[i] = 0;
  238.     if (m < 3) b_size = m;
  239.     for(i=0; i<D+1; i++) {
  240.         j = M-1 - m*i;
  241.         hash = 0;
  242.         for(k=0; k<b_size; k++) {
  243.             hash = (hash << 2) + Pattern[j-k];
  244.         }
  245. #ifdef DEBUG
  246.     printf(" hash = %d,", hash);
  247. #endif
  248.         MEMBER[hash] = 1;
  249.     }
  250. }
  251.  
  252.  
  253. agrep( pat, M, text, textend, D ) 
  254. int M, D ; register CHARTYPE *text, *textend, *pat;
  255. {
  256.   register int i;
  257.   register int m = M/(D+1);
  258.   register CHARTYPE *textstart;
  259.   register int shift, HASH;
  260.   int  j=0, k, m1, d1;
  261.   int  n, cdx;
  262.   int  Candidate[MaxCan][2], round, lastend=0;
  263.   unsigned R1[MaxError+1], R2[MaxError+1]; 
  264.   register unsigned int r1, endpos, c; 
  265.   unsigned currentpos;
  266.   unsigned Bit1;
  267.   unsigned r_newline;
  268.  
  269.   Candidate[0][0] = Candidate[0][1] = 0; 
  270.   d1 = shift_1;
  271.   cdx = 0;
  272.   if(m < 3) r1 = m;
  273.   else r1 = 3;
  274.   textstart = text;
  275.   shift = m-1;
  276.   while (text < textend) {
  277.     shift = SHIFT[*(text += shift)];
  278.     while(shift) {
  279.         shift = SHIFT[*(text += shift)];
  280.         shift = SHIFT[*(text += shift)];
  281.     }
  282.         j = 1; HASH = *text;
  283.         while(j < r1) { HASH = (HASH << 2) + *(text-j);
  284.                 j++; }
  285.             if (MEMBER[HASH]) { 
  286.             i = text - textstart;
  287.                          if((i - M - D - 10) > Candidate